package common.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//import sysmgt.entity.UserEntity;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * 使用jackson操作JSON的工具类
 * 
 * @author liuxj
 * @version 1.0.0 2017-08-31
 */
@SuppressWarnings("unchecked")
public class JacksonUtils {
    /**
     * 获得ObjectMapper对象，默认输出全部属性到Json字符串
     * 
     * @return ObjectMapper
     */
    public static ObjectMapper getObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        
        return objectMapper;
    }

    /**
     * 获得ObjectMapper对象，并设置转换日期的格式，默认输出全部属性到Json字符串
     * 
     * @param pattern
     *            日期格式
     * @return ObjectMapper
     */
    public static ObjectMapper getObjectMapper(String pattern) {
        ObjectMapper objectMapper = getObjectMapper();
        setDateFormat(objectMapper, pattern);

        return objectMapper;
    }

    /**
     * 设置转换日期的格式，如果不设置默认是Timestamp毫秒数<br/>
     * 日期格式参考:"yyyy-MM-dd HH:mm:ss,SS"或"yyyy-MM-dd hh:mm:ss,SS"
     * 
     * @param objectMapper
     *            ObjectMapper
     * @param pattern
     *            日期格式
     */
    public static void setDateFormat(ObjectMapper objectMapper, String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        objectMapper.setDateFormat(dateFormat);
    }

    /**
     * 将对象转换成JSON字符串，如果转换出错则返回null
     * 
     * @param obj
     *            要转换的对象
     * @return JSON字符串
     */
    public static String objectToJson(Object obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }

    /**
     * 将对象转换成JSON字符串，如果转换出错则返回null
     * 
     * @param obj
     *            要转换的对象
     * @param pattern
     *            日期格式
     * @return JSON字符串
     */
    public static String objectToJson(Object obj, String pattern) {
        try {
            return getObjectMapper(pattern).writeValueAsString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }

    /**
     * 将JSON字符串转换为相应的对象，如果转换出错则返回null
     * 
     * @param json
     *            JSON字符串
     * @param clazz
     *            泛型对象
     * @return 转换后的对象
     */
    public static <T> T jsonToObject(String json, Class<T> clazz) {
        try {
            return getObjectMapper().readValue(json, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    /**
     * 将Map字符串转换为相应的对象，如果转换出错则返回null
     * 
     * @param data
     *            Map<String, Object>
     * @param clazz
     *            泛型对象
     * @return 转换后的对象
     */
    public static <T> T mapToObject(Map<String, Object> data, Class<T> clazz) {
        try {
            return getObjectMapper().convertValue(data, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    /**
     * 将JSON字符串转换为Map，如果转换出错则返回null
     * 
     * @param json
     *            JSON字符串
     * @return Map<String, Object>
     */
    public static Map<String, Object> jsonToMap(String json) {
        try {
            return getObjectMapper().readValue(json, Map.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
    /**
     * 将JSON字符串转换为List，如果转换出错则返回null
     * <br><br>
     * 注意：<br>
     * JSON格式必须与下面的JSON格式一致，否则就会报错：<br>
     * [{"username":"u1","password":"123"},{"username":"u2","password":"123"}]
     * 
     * @param json
     *            JSON字符串
     * @return List<T>
     */
    public static <T> List<T> jsonToList(String json, Class<T> clazz) {
        try {
            List<T> result = new ArrayList<T>();
            
            List<Map<String,Object>> list = getObjectMapper().readValue(json, new TypeReference<List<T>>() {});
            for (Map<String, Object> map : list) {
                result.add(mapToObject(map, clazz));
            }

            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
    
    public static void main(String[] args) {
        String json = "[{\"username\":\"admin\",\"password\":\"admin\"},{\"username\":\"123\",\"password\":\"123\"}]";
        
//        List<UserEntity> userList = jsonToList(json, UserEntity.class);
//        //System.out.println(userList);
//
//        json = "{\"username\":\"admin\",\"password\":\"admin\"}";
//
//        UserEntity user = jsonToObject(json, UserEntity.class);
        //System.out.println(user);
    }
}
